This invention relates generally to a computer method and system for managing objects and, in particular, a method and system for locating enclosing objects.
The use of object-oriented programming techniques can facilitate the development of complex computer programs. Programming languages that support object-oriented techniques are being used to develop these programs. One such programming language is C++. Two common characteristics of object-oriented programming language in general and of the C++ programming language are support for data encapsulation and data-type inheritance. Data encapsulation refers to the binding of functions and data-type inheritance refers to the ability to declare a data type in terms of other data types.
In the C++ programming language, object-oriented techniques are supported through the use of classes. A class is a user-defined type. A class definition describes data members and function members of the class. For example, the following is a definition of a class named Bicycle.
The class Bicycle as shown contains data members that describe the characteristics of a bicycle, such as height and number of sprockets. The data members named Height, SprocketF, and SprocketB are declared to be integers. The data members named TireF and TireB are declared to be objects of class Tire. The following is a definition of a class named Tire.
The class Tire includes data members that describe the characteristics of a tire, such as the radius, the width, and the speed in revolutions per minute of the tire.
In the syntax of the C++ programing language, the following statement declares an object named Bike to be of type Bicycle.
Bicycle Bike;
This declaration causes the allocation of memory for an object named Bike, such an allocation is also called an instance of the class Bicycle. FIG. 1A illustrates the layout of memory for an object of type Bicycle. The Bike object contains a virtual function pointer 101, the Height data member 102, the SprocketF data member 103, the SprocketB data member 104, the TireF data member 105, and the TireB data member 106. A typical C++ compiler automatically allocates virtual function pointers for a class that declares a function member to be virtual. The memory layout includes instances of the type Tire for the TireF and TireB data members. The TireF and TireB objects include the Radius data members 105b, 106b, the Width data members 105c, 106c, and the RPM data members 105d, 106d. The TireF and TireB objects are considered to be embedded within the Bike object, since the TireF and TireB objects are data members of the class Bicycle. Thus, the TireF and TireB objects are considered to be embedded objects, and the Bike object is considered to be an enclosing object.
Certain object-oriented database systems provide application programs with access to the data of the database through C++-like objects. For example, if the database contains information describing various bicycles, then when an application program needs to access information relating to a certain bicycle, the database system would instantiate an object of a class Bicycle. The database system would then initialize the data members of the Bicycle object based on the data in the database for that bicycle. The database system would then provide the application program with a reference (e.g., the object address which is typically the first memory location allocated to the object) to the Bicycle object. The application program could then access the data members of the Bicycle object using the reference. In the following, the term xe2x80x9cdatabase objectsxe2x80x9d refers to the data that is persistently stored by a database system and the term xe2x80x9cobjectxe2x80x9d refers to an in-memory instance of a class that may contain the data of a database object.
Databases are typically transaction-oriented. A transaction is a sequence of modifications to a database that needs to be performed as a unit. That is, if one of the modifications in the sequence is made, then each modification in the sequence must also be made. To effect transaction processing, a database system would typically allow an application program to instantiate and modify objects corresponding to the database objects to be modified as part of the transaction. Once all the objects have been modified, then the application program would request the database system to xe2x80x9ccommitxe2x80x9d those modifications. In response, the database system would cause the modifications to be stored persistently, for example, on a disk. When a transaction is to be committed, the database system needs to locate all instantiated objects so that the corresponding database objects can be updated. Database systems can use a couple of different approaches to locate the instantiated objects. First, the database system could maintain a table that contains a reference to each object that was instantiated as part of the transaction. However, such an approach may be unacceptable because of the amount of memory needed to store the table and because of the amount of processing needed to maintain the table. Second, the database system could simply maintain a small table that contains references to xe2x80x9crootxe2x80x9d objects of the transaction. The root objects are those objects from which each other object that was instantiated as part of the transaction are accessible. In such a case, the database system would start with a root object, and persistently store the data for that root object. If the root object contains pointers to other objects, then the database system would persistently store the data for those referenced objects in the database. The database system would repeat this process in a transitive manner for each object that is referenced through each root object. Although this second approach overcomes the overhead of maintaining a large table, the approach does not properly handle references to embedded objects.
Certain objects may contain references that point to embedded objects rather than the enclosing-objects. FIG. 1B illustrates references that point to embedded objects. The root object points to the TireF and TireB objects that are embedded within the Bicycle object. The database system may have generated such references in the following way. The application program may have requested access to a certain root object that has references to the Tire objects for a certain make and model of bicycle (e.g., Schwinn/10-speed). The database system would instantiate a Bicycle object, but then store a reference to the embedded Tire objects in the root object, rather than storing a reference to the Bicycle object. When committing a transaction, the database system would need to determine which Bicycle object contains the embedded Tire objects so the tire information for the appropriate database object (e.g., Schwinn/10-speed) could be updated. When the database system follows a pointer to a Tire object, it needs to determine whether the object is embedded. If the object is embedded, the database system needs to retrieve or generate a reference to the enclosing object so that it can identify the database object from information that is in the enclosing object, but not within the embedded object.
Unfortunately, programming languages, such as the C++ programming language, do not provide a mechanism by which the location of an enclosing object can be determined from an embedded object. It would be desirable to have a mechanism by which a database system could determine the location of the enclosing object from a reference to an embedded object.
The present invention provides a computer-based method and system for identifying the most-enclosing object that encloses an object of a class. When an object of the class is instantiated within an enclosing object (i.e., embedded), the system sets a data member of the instantiated object to indicate an offset between the start of the instantiated object to the start of a nearest enclosing object. When an object of a class is not instantiated within an enclosing object, the system sets the data member of the instantiated object to indicate a zero offset. When the system receives a reference to an instantiated object, the system repeats the following until the reference points to a most-enclosing object. The system retrieves the offset from the object referenced by the current value of the reference. The system combines the retrieved offset with the current value of the reference to generate a new reference that references the nearest enclosing object of the previously referenced object. When the offset is zero, then the reference points to the most-enclosing object.